/*

Copyright (C) 2008 Victor Manuel Sanchez Cartagena, Juan Antonio Perez Ortiz


This file is part of ANTLRArbol.

ANTLRArbol is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

ANTLRArbol is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/. 

*/

grammar Prefix; 
 
/* Traduce con ANTLR un fichero de expresiones infijas separadas por punto  
   y coma a notación prefija. Usa una gramática BNF. 
*/  
 
@header { 
import java.lang.String; 
} 
 
prog:   (stat ';')+ ; 
                 
stat:   expr {System.out.println($expr.s);} 
    ; 
 
expr returns [String s] 
    :    term expr_prima[$term.s] {$s = $expr_prima.s;}  
    ; 
 
 
/* Sería mejor concatenar las cadenas en el propio parámetro: 
  
      '+' term expr_prima["suma(" + $sh + "," + $term.s + ")"] {$s = $expr_prima.s;}  
 
   Pero ANTLR genera código incorrecto en este caso :-( 
*/ 
 
expr_prima [String sh] returns [String s] 
@init{ 
  String p= null; 
} 
    :   '+' term {p="suma(" + $sh + "," + $term.s + ")";} e=expr_prima[p] {$s = $e.s;}  
    |   '-' term {p="resta(" + $sh + "," + $term.s + ")";} e=expr_prima[p] {$s = $e.s;} 
    |   {$s = $sh;} 
    ; 
 
term returns [String s] 
    :    factor term_prima[$factor.s] {$s = $term_prima.s;}  
    ; 
 
term_prima [String sh] returns [String s] 
@init{ 
  String p= null; 
} 
    :   '*' factor {p="mult(" + $sh + "," + $factor.s + ")";} t=term_prima[p] {$s = $t.s;} 
    |   {$s = $sh;} 
    ; 
 
factor returns [String s] 
    :   INT {$s = $INT.text;} 
    |   ID {$s = $ID.text;} 
    |   '(' expr ')' {$s = $expr.s;} 
    ; 
 
ID      :    ('a'..'z'|'A'..'Z')+ ; 
INT     :    '0'..'9'+ ; 
NEWLINE    :    ('\r'? '\n'|' '|'\t')+  {skip();}  
    ; 
 COMENTARIO 
    :    '/*' .* '*/' {skip();} 
    ; 
COMENTARIO_LINEA 
    : '//' ~('\n'|'\r')* '\r'? '\n' {skip();} 
    ; 
